#include <iostream>
#include <string>
#include <cstring>
#include <regex>
#include "QueryTreeTuple.h"
using namespace std;

SymbolTuple::SymbolTuple(design_entity type, string name){
	this->type = type;
	this->name = name;
}

design_entity SymbolTuple::getType(){
	return this->type;
}
	
string SymbolTuple::getName(){
	return this->name;
}

string SymbolTuple::toString() {
	return "SymbolTuple name: " + name;
}
ResultClauseTuple::ResultClauseTuple(symbolIndex s, attr_Name a) {
	symbol = s;
	attribute = a;
}

attr_Name ResultClauseTuple::getAttribute() {
	return attribute;
}

symbolIndex ResultClauseTuple::getSymbolIndex() {
	return symbol;
}

string ResultClauseTuple::toString() {
	return "Index: "+ symbol;
}

RelationTuple::RelationTuple(relationType relRef){
	this->relRef = relRef;

}

void RelationTuple::setArg(int argument, int argumentNum) {
	switch(argumentNum) {
	case 1:
		numberArg1 = argument;
		arg1Type = number;
		break;
	case 2:
		numberArg2 = argument;
		arg2Type = number;
		break;
	default:
		break;	//catch error?
	}
}

void RelationTuple::setArg(symbolIndex argument, int argumentNum){
	switch(argumentNum) {
	case 1:
		symbolArg1 = argument;
		arg1Type = symbol;
		break;
	case 2:
		symbolArg2 = argument;
		arg2Type = symbol;
		break;
	default:
		break;	//catch error?
	}
}
void RelationTuple::setArg(string argument, int argumentNum){
	switch(argumentNum) {
	case 1:
		nameArg1 = argument;
		arg1Type = name;
		break;
	case 2:
		nameArg2 = argument;
		arg2Type = name;
		break;
	default:
		break;	//catch error?
	}
}

string RelationTuple::getNameArg(int argumentNum) {
	switch(argumentNum) {
	case 1:
		return nameArg1;
	case 2:
		return nameArg2;
	default:
		break;	//catch error?
	}
}
int RelationTuple::getNumberArg(int argumentNum) {
	switch(argumentNum) {
	case 1:
		return numberArg1;
	case 2:
		return numberArg2;
	default:
		break;	//catch error?
	}
}
symbolIndex RelationTuple::getSymbolArg(int argumentNum) {
	switch(argumentNum) {
	case 1:
		return symbolArg1;
	case 2:
		return symbolArg2;
	default:
		break;	//catch error?
	}
}

relationType RelationTuple::getrelRef(){
	return this->relRef;
}

refType RelationTuple::getRefType(int argumentNum) {
	switch(argumentNum) {
	case 1:
		return arg1Type;
	case 2:
		return arg2Type;
	default:
		break;	//catch error?
	}
}

string RelationTuple::toString() {
	string builder = "argument1 type: ";
	switch(arg1Type) {
	case name:
		builder = builder + "name " + nameArg1 +" argument2 type: ";
		break;
	case number:
		builder = builder + "number argument2 type: ";
		break;
	case symbol:
		builder = builder + "symbol argument2 type: ";
		break;
	default:
		break;
	}

	switch(arg2Type) {
	case name:
		builder = builder + "name " + nameArg2;
		break;
	case number:
		builder = builder + "number";
		break;
	case symbol:
		builder = builder + "symbol";
		break;
	default:
		break;
	}

	return builder;
}
/*string RelationTuple::getArgA(){
	return this->argA;
}

string RelationTuple::getArgB(){
	return this->argB;
}

symbolIndex RelationTuple::getArg1(){
	return this->arg1;
}

symbolIndex RelationTuple::getArg2(){
	return this->arg2;
}*/

/*WithClauseTuple::WithClauseTuple(symbolIndex symbol, attr_Name attrName, string ref){
	this->symbol = symbol;
	this->attrName = attrName;
	this->ref = ref;
}*/

WithClauseTuple::WithClauseTuple(symbolIndex symbol, attr_Name attrName){
	this->symbol = symbol;
	this->attrName = attrName;
}

void WithClauseTuple::setRef(string name_) {
	nameRef = name_;
	referenceType = name;
}

void WithClauseTuple::setRef(int num) {
	numberRef = num;
	referenceType = number;
}

string WithClauseTuple::getNameRef() {
	return nameRef;
}

int WithClauseTuple::getNumRef() {
	return numberRef;
}

symbolIndex WithClauseTuple::getSymbol(){
	return this->symbol;
}

attr_Name WithClauseTuple::getAttrName(){
	return this->attrName;
}

string WithClauseTuple::toString() {
	switch(referenceType) {
	case number:
		return "number referece";
		break;
	case name:
		return "name reference";
		break;
	default:
		break;
	}
}

refType WithClauseTuple::getRefType() {
	return referenceType;
}

/*string WithClauseTuple::getRef(){
	return this->ref;
}*/

PatternTuple::PatternTuple(symbolIndex symbol, string entRef, string subExpression ){
	this->symbol = symbol;
	this->entRef = entRef;
	this->subExpression = subExpression;
}

symbolIndex PatternTuple::getSymbol(){
	return this->symbol;
}

string PatternTuple::getEntRef(){
	return this->entRef;
}

string PatternTuple::getSubExpression(){
	return this->subExpression;
}